package app.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

//import org.springframework.cache.interceptor.KeyGenerator;

/**
 * spring-cache的缓存配置文件
 */
@Configuration
//开启缓存
@EnableCaching
public class RedisConfig2 {
    //配置redis的过期时间
    private Duration timeToLive = Duration.ZERO;

    public void setTimeToLive(Duration timeToLive) {
        this.timeToLive = timeToLive;
    }


    /**
     * 设置手动存的序列化方式
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        //得到redistemplate对象
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        //设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //实例化一个GenericJackson2JsonRedisSerializer 序列化方式
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //设置value的序列化方式
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        //设置hashvalue的序列化方式
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        //设置key的序列化方式 为 StringRedis  注意 和value的序列化方式不同
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置hashkey
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        //非spring注入使用RedisTemplate,需先调用afterPropertiesSet()方法,此方法是应该是初始化参数和初始化工作。
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * 统一管理spting的cache
     *
     * @param factory redis的连接工厂
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        //新建一个Jackson2JsonRedis的redis存储的序列化方式
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //解决查询缓存转换异常的问题
        // 配置序列化（解决乱码的问题）
        //entryTtl设置过期时间
        //serializeValuesWith设置redis存储的序列化方式
        //.defaultCacheConfig()先调用默认配置，然后再做部分修改，相当于是调了个super()
        RedisCacheConfiguration config = RedisCacheConfiguration
                .defaultCacheConfig()
                .entryTtl(timeToLive)
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer))
                .disableCachingNullValues();
        //定义要返回的redis缓存管理对象
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }

}
